package com.xyzwps.harbor.handler.filter;

import com.xyzwps.harbor.model.User;
import com.xyzwps.harbor.service.SessionService;
import com.xyzwps.harbor.service.UserService;
import com.xyzwps.harbor.util.Dict;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.server.HandlerFilterFunction;
import org.springframework.web.reactive.function.server.HandlerFunction;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Mono;

import static com.xyzwps.harbor.util.HarborException.*;

@Component
public class AuthFilter implements HandlerFilterFunction<ServerResponse, ServerResponse> {

    @Autowired
    private SessionService sessionService;

    @Autowired
    private UserService userService;

    @Override
    public Mono<ServerResponse> filter(ServerRequest req, HandlerFunction<ServerResponse> next) {
        var sidCookie = req.cookies().getFirst(Dict.COOKIE_SID);
        if (sidCookie == null) {
            throw badRequestEx("unauthenticated" );
        }

        var sid = sidCookie.getValue();
        return sessionService.getAliveSession(sid)
                .flatMap(session -> userService.getUserByUserId(session.getUserId()))
                .switchIfEmpty(Mono.error(incorrectCode("no corresponding user" )))
                .map(User::shouldBeActive)
                .flatMap(user -> {
                    req.attributes().put(Dict.REQ_USER_INFO, user);
                    return next.handle(req);
                });
    }
}
